package com.ease.database.ddl.initializer;

import java.util.List;

import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import com.ease.dao.JdbcTemplateDataAccessObject;
import com.ease.model.DatabaseColumn;
import com.ease.model.DatabaseTable;
import com.ease.platform.access.service.DatabaseColumnAccessService;
import com.ease.platform.access.service.DatabaseTableAccessService;
import com.obas.access.metadata.service.IndicatorTypeAccessService;
import com.obas.business.analogy.util.AnalogyTableNameUtil;
import com.obas.model.type.AnalogyDimensionAttributeType;
import com.obas.model.type.AnalogyDimensionType;
import com.obas.model.type.AnalogyValueAttributeType;
import com.obas.model.type.AttributeColumnType;
import com.obas.model.type.BaseHeadAttributeType;
import com.obas.model.type.BaseValueAttributeType;
import com.obas.model.type.DimensionAttributeType;
import com.obas.model.type.ProcessDimensionType;
import com.obas.model.type.TimeDimensionType;
import com.obas.test.ApplicationContextUserContextTest;

public class AnalogyTableInitializer extends ApplicationContextUserContextTest {

	@Autowired
	JdbcTemplateDataAccessObject jdbcTemplateDataAccessObject;

	@Autowired
	DatabaseTableAccessService databaseTableAccessService;

	@Autowired
	DatabaseColumnAccessService databaseColumnAccessService;

	@Autowired
	IndicatorTypeAccessService indicatorTypeAccessService;

	@Test
	public void init() {

		AnalogyDimensionType[] analogyDimensionTypes = AnalogyDimensionType.enabledValues();

		ProcessDimensionType[] processDimensionTypes = ProcessDimensionType.values();

		for (AnalogyDimensionType analogyDimensionType : analogyDimensionTypes) {
			DimensionAttributeType[] dimensionAttributeTypes = AnalogyDimensionAttributeType.getByAnalogyDimensionType(analogyDimensionType);

			TimeDimensionType timeDimensionType = null;
			// TimeDimensionType[] timeDimensionTypes = TimeDimensionType.values();
			// for (TimeDimensionType timeDimensionType : timeDimensionTypes) {
			// }
			//
			// timeDimensionType = TimeDimensionType.MINUTE;
			// for (ProcessDimensionType processDimensionType : processDimensionTypes) {
			// init(analogyDimensionType, timeDimensionType, processDimensionType, dimensionAttributeTypes);
			// }
			timeDimensionType = TimeDimensionType.HOUR;
			for (ProcessDimensionType processDimensionType : processDimensionTypes) {
				init(analogyDimensionType, timeDimensionType, processDimensionType, dimensionAttributeTypes);
			}
			timeDimensionType = TimeDimensionType.DAY;
			for (ProcessDimensionType processDimensionType : processDimensionTypes) {
				init(analogyDimensionType, timeDimensionType, processDimensionType, dimensionAttributeTypes);
			}
			timeDimensionType = TimeDimensionType.WEEK;
			for (ProcessDimensionType processDimensionType : processDimensionTypes) {
				init(analogyDimensionType, timeDimensionType, processDimensionType, dimensionAttributeTypes);
			}
			timeDimensionType = TimeDimensionType.MONTH;
			for (ProcessDimensionType processDimensionType : processDimensionTypes) {
				init(analogyDimensionType, timeDimensionType, processDimensionType, dimensionAttributeTypes);
			}
		}
	}

	public void init(AnalogyDimensionType analogyDimensionType, TimeDimensionType timeDimensionType, ProcessDimensionType processDimensionType, DimensionAttributeType[] dimensionAttributeTypes) {
		String tableName = null;
		if (ProcessDimensionType.KPI_BASE.equals(processDimensionType) || //
				ProcessDimensionType.KQI_BASE.equals(processDimensionType)) {
			tableName = AnalogyTableNameUtil.baseTableName(processDimensionType);
		} else {
			tableName = AnalogyTableNameUtil.tableName(analogyDimensionType, timeDimensionType, processDimensionType);
		}

		DatabaseTable databaseTable = databaseTableAccessService.findByTableName(tableName);
		if (null == databaseTable) {
			jdbcTemplateDataAccessObject.getJdbcTemplate().execute("CREATE TABLE " + tableName + " (BATCHTIMESTAMP DATE)");
			// TODO: comment on table table_name is 'comments';
			// jdbcTemplateDataAccessObject.getJdbcTemplate().execute("drop sequence " +
			// AnalogyTableNameUtil.oracleName("SEQ_" + tableName));
			// jdbcTemplateDataAccessObject.getJdbcTemplate().execute("create sequence " +
			// AnalogyTableNameUtil.sequenceName("SEQ_" + tableName));
			// jdbcTemplateDataAccessObject.getJdbcTemplate().execute("alter table " + tableName + " add constraint " +
			// AnalogyTableNameUtil.sequenceName("PK_" + tableName) + " primary key (ID)");
		}

		//
		List<DatabaseColumn> databaseColumns = databaseColumnAccessService.findByTableName(tableName);

		
		
		if(TimeDimensionType.HOUR.equals(timeDimensionType)){
			initColumn(tableName, AnalogyValueAttributeType.HOUR_OF_DAY, databaseColumns);
		}
		
		if(TimeDimensionType.DAY.equals(timeDimensionType)){
			initColumn(tableName, AnalogyValueAttributeType.DAY_OF_WEEK, databaseColumns);
		}
		
		if(TimeDimensionType.WEEK.equals(timeDimensionType)){
			initColumn(tableName, AnalogyValueAttributeType.WEEK_OF_YEAR, databaseColumns);
		}
		
		if(TimeDimensionType.MONTH.equals(timeDimensionType)){
			initColumn(tableName, AnalogyValueAttributeType.MONTH_OF_YEAR, databaseColumns);
		}
		
		{
			initColumn(tableName, AnalogyValueAttributeType.INDICATORTYPE_ID, databaseColumns);
			initColumn(tableName, AnalogyValueAttributeType.NETWORKSERVING_ID, databaseColumns);
		}

		BaseHeadAttributeType[] baseHeadAttributeTypes = BaseHeadAttributeType.values();
		BaseValueAttributeType[] baseValueAttributeTypes = BaseValueAttributeType.values();

		if (ProcessDimensionType.KPI_BASE.equals(processDimensionType) || //
				ProcessDimensionType.KQI_BASE.equals(processDimensionType)//
		) {
			for (BaseHeadAttributeType attributeColumnType : baseHeadAttributeTypes) {
				initColumn(tableName, attributeColumnType, databaseColumns);
			}
		}

		if (ProcessDimensionType.KPI_AGG.equals(processDimensionType) || //
				ProcessDimensionType.KQI_AGG.equals(processDimensionType) || //
				ProcessDimensionType.KQI_ACC.equals(processDimensionType) || //
				ProcessDimensionType.KQI_ACC_CYCLE.equals(processDimensionType)//
		) {
			if (null != dimensionAttributeTypes) {
				for (DimensionAttributeType attributeColumnType : dimensionAttributeTypes) {
					initColumn(tableName, attributeColumnType, databaseColumns);
				}
			}
		}

		//
		if (ProcessDimensionType.KPI_BASE.equals(processDimensionType) || //
				ProcessDimensionType.KPI_AGG.equals(processDimensionType)//
		) {
			for (BaseValueAttributeType attributeColumnType : baseValueAttributeTypes) {
				initColumn(tableName, attributeColumnType, databaseColumns);
			}
		}

		//
		if (ProcessDimensionType.KPI_BASE.equals(processDimensionType) || //
				ProcessDimensionType.KPI_AGG.equals(processDimensionType)//
		) {
			initColumn(tableName, AnalogyValueAttributeType.SUMMATION, databaseColumns);
		}

		//
		if (ProcessDimensionType.KQI_BASE.equals(processDimensionType) || //
				ProcessDimensionType.KQI_AGG.equals(processDimensionType) || //
				ProcessDimensionType.KQI_ACC.equals(processDimensionType) || //
				ProcessDimensionType.KQI_ACC_CYCLE.equals(processDimensionType)//
		) {
			initColumn(tableName, AnalogyValueAttributeType.VALUE, databaseColumns);
		}

		//
		if (			ProcessDimensionType.KQI_AGG.equals(processDimensionType) //
		) {
			initColumn(tableName, AnalogyValueAttributeType.RANK, databaseColumns);
		}
		
		
		
		//
		if (ProcessDimensionType.KQI_ACC.equals(processDimensionType) || //
				ProcessDimensionType.KQI_ACC_CYCLE.equals(processDimensionType)) {
			initColumn(tableName, AnalogyValueAttributeType.ACCUMULATIONS, databaseColumns);
		}

	}

	void initColumn(String tableName, String columnName, int length, String dataType, List<DatabaseColumn> databaseColumns) {
		DatabaseColumn databaseColumn = databaseColumnOf(databaseColumns, columnName);
		if (null == databaseColumn) {
			jdbcTemplateDataAccessObject.getJdbcTemplate().execute("alter table " + tableName + " add " + columnName + " " + dataType + (length > 0 ? "(" + length + ")" : ""));
			// TODO: comment on column table.column_name is 'comments';
		}
	}

	void initColumn(String tableName, AttributeColumnType attributeColumnType, List<DatabaseColumn> databaseColumns) {
		String columnName = attributeColumnType.getColumnName();
		int length = attributeColumnType.getLength();
		String dataType = attributeColumnType.getDataType();

		initColumn(tableName, columnName, length, dataType, databaseColumns);
	}

	static DatabaseColumn databaseColumnOf(List<DatabaseColumn> databaseColumns, String columnName) {
		if (null != databaseColumns && null != columnName) {
			for (DatabaseColumn databaseColumn : databaseColumns) {
				if (columnName.equals(databaseColumn.getColumnName())) {
					return databaseColumn;
				}
			}
		}
		return null;
	}
}
